
//
// 130515 - AH - Created.
// 130604 - AH - Missing java doc.
//

package org.socratons.service;

import java.io.IOException;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.japril.gim.Item;
import org.japril.gim.ItemItem;
import org.japril.gim.Items;
import org.japril.gim.ItemsKeyMap;
import org.japril.gim.sql.SqlItems;
import org.japril.jutil.CharArrayPrintWriter;

/**
 * <p>
 *   Performs update and request to GIM realizing a Socratons storage.
 * </p>
 * @author Arne Halvorsen (AH)
 */
public final class SocratonsAccess 
{
  private final Items m_items;
  
  /**
   * <p>
   *   Constructor.
   * </p>
   * @param con Connection to RDBMS.
   * @throws IOException If fails.
   */
  public SocratonsAccess(Connection con) throws IOException
  {
    m_items=new SqlItems(con);    
  }
  
  /**
   * <p>
   *   Update a 
   *   {@code Socraton}'s data.
   * </p>
   * @param id        {@code Socraton}'s id.
   * @param bisonsMap Data of
   *                  {@code Bison} 
   *                  {@code Socraton} (values) grouped by context (keys).
   * @return Log text.
   * @throws IOException If fails.
   */
  public String update(String id, Map<String, List<String>> bisonsMap) 
    throws IOException
  {
    CharArrayPrintWriter capw=new CharArrayPrintWriter();
    StringBuilder sb=new StringBuilder();
    
    sb.append("look for socraton with id=").append(id);
    capw.println(sb);
    
    // Find socraton.
    Item socratonItem=m_items.getItemWithProperty("id", id, "socraton");
    if (socratonItem==null)
    {
      sb.setLength(0);
      sb.append("socraton with id=").append(id).append(" not found, create it");
      capw.println(sb);
      
      socratonItem=m_items.create("socraton");
      m_items.setProperty(socratonItem, "id", id);
    }
    else
    {
      sb.setLength(0);
      sb.append("socraton with id=").append(id).append(" found");
      capw.println(sb);
    }
    
    for (Map.Entry<String, List<String>> curr : bisonsMap.entrySet())
    {
      String context=curr.getKey();
      String rrel="ctx:"+context;
      
      List<String> data=curr.getValue();
      
      for (String cd : data)
      {
        Item bisonItem=m_items.getItemWithProperty("data", data, "bison");
        if (bisonItem==null)
        {
          sb.setLength(0);
          sb.append("bison data with data '").append(data)
            .append("' does not exists, creates it and make relationship");
          capw.println(sb);
          
          bisonItem=m_items.create("bison");
          m_items.setProperty(bisonItem, "data", cd);
          m_items.createRelation(socratonItem, bisonItem, rrel);
        }
        else
        {
          sb.setLength(0);
          sb.append("bison data with data '").append(data)
            .append("' does exists, check if relationship exists");
          capw.println(sb);
          
          List<Item> coll=m_items.getRightItems(socratonItem, rrel);
          ItemsKeyMap map=new ItemsKeyMap(coll);
          if (!map.contains(bisonItem.getId()))
          {
            sb.setLength(0);
            sb.append("relationship does not exists, creates it");
            capw.println(sb);
            
            m_items.createRelation(socratonItem, bisonItem, rrel);
          }
          else
          {
            sb.setLength(0);
            sb.append("relationship exists, nothing to do");
            capw.println(sb);
          }
        }
      }
    }
    
    return capw.toString();
  }
  
  /**
   * <p>
   *   Gets XML that contains all pool.
   * </p>
   * @return XML.
   * @throws IOException If fails.
   */
  public String copy() throws IOException
  {
    List<SocData> sdl=new ArrayList<SocData>();
    
    CharArrayPrintWriter capw=new CharArrayPrintWriter();
    
    List<Item> socs=m_items.getItems("socraton");
    for (Item item : socs)
    {
      int id=item.getId();
      
      String sid=m_items.getStringProperty(id, "id");
      
      SocData sd=new SocData(sid, "socraton-service");
      
      List<ItemItem> brel=m_items.getRelations(id, "bisons");
      for (ItemItem ii : brel) 
      {
        String rrole=ii.getRightRole();
        if (rrole.startsWith("ctx:"))
        {
          String context=rrole.substring(4);
          context=(context==null) ? "" : context.trim();
          if (context.length()>0)
          {
            int rid=ii.getRightId();
            Item bison=m_items.getItem(rid);
            if (bison!=null)
            {
              String data=m_items.getStringProperty(bison, "data");
              data=(data==null) ? "" : data.trim();
              if (data.length()>0) sd.addBisonData(context, data);
            }
          }
        }
      }
      
      capw.println(sd);
      sdl.add(sd);
    }
    
    SocratonsXmlProtocolCompiler comp=new SocratonsXmlProtocolCompiler();
    return comp.socratons(sdl).compile();
  }
  
}
